/*
  ==============================================================================

    KSVoice.h
    Created: 25 Nov 2014 4:34:07pm
    Author:  Alistair Barker

  ==============================================================================
*/

#ifndef KSVOICE_H_INCLUDED
#define KSVOICE_H_INCLUDED

#include "PluginProcessor.h"

#include "../JuceLibraryCode/JuceHeader.h"

#include "DelayLine.h"
#include "RMS.h"

const int WAVETABLE_LENGTH = 4096;
const int movingAverageCount = 500;
enum ksVoiceStateType {off, impulse, tail};

class KSSound : public SynthesiserSound
{
public:
    KSSound() {}
    
    bool appliesToNote (const int /*midiNoteNumber*/)           { return true; }
    bool appliesToChannel (const int /*midiChannel*/)           { return true; }
};

class KSVoice : public SynthesiserVoice, public Value::Listener
{
public:
    KSVoice(KarplusStrongAudioProcessor& p);
    ~KSVoice();

    virtual bool canPlaySound (SynthesiserSound* sound);
    
    virtual void startNote (const int midiNoteNumber,
                            const float velocity,
                            SynthesiserSound* sound,
                            const int currentPitchWheelPosition);
    
    virtual void stopNote (float velocity, bool allowTailOff);
    
    virtual void pitchWheelMoved (const int newValue) {}
    
    virtual void controllerMoved (const int controllerNumber,
                                  const int newValue) {}
    
    virtual void renderNextBlock (AudioSampleBuffer& outputBuffer,
                                  int startSample,
                                  int numSamples);
    
    double RMSValue;
    
    virtual void valueChanged (Value& value);

    virtual void changeNumDelays (int newNumStrings);
    
private:
    
    double noiseWavetable[WAVETABLE_LENGTH];
    int wavetablePointer;
    Envelope* noiseEnv;
    double noiseDecay;
    double noiseAttack;
    double getExcitationSample();
    
    bool checkRMS(double input);
    void setDelaysWithDetune(double detune, int numDelays);
    void setResonance(int note);

    double resonance;
    
    RMS RMSChecker;
    
    KarplusStrongAudioProcessor& processor;
    
    Generator* generator;
 
    int state;
    int currentNote;
    
    OwnedArray<DelayLine> delays;
    OwnedArray<IIRFilter> feedbackFilters;
    
    
    
};

#endif  // KSVOICE_H_INCLUDED
